package travianBot.botScripts;

import java.io.IOException;
import java.util.HashMap;
import java.util.Random;

import org.apache.log4j.Logger;


import travianBot.TravianBot;
import travianBot.TravianBotException;
import travianBot.TravianBotUtil;
import travianBot.Village;


public class TravianScriptRunner extends Thread{
	static Logger log=Logger.getLogger(TravianScriptRunner.class);
	TravianBot bot = new TravianBot();
	ScriptContainer scriptContainer = new ScriptContainer();
	boolean stillRunning = true;
	public int loopMax=10000000;
	public static final String NEWLINE = System.getProperty("line.separator");
	public int sleepMinutes = 10;
	public static final String password = "Banana123";
	public static final String username = "mike.uk";
	
	
	/**
	 * run the script and call the bot methods to run upgrades
	 * @param resourceScript
	 * @return
	 * @throws TravianBotException
	 */
	
	/**
	 * login and load the village list
	 * @param theBot
	 * @throws TravianBotException 
	 */
	public void initBot(TravianBot theBot, String username, String password) throws TravianBotException{
		String htmlResourcePage = "";
		
		htmlResourcePage = theBot.login(username, password);
			
		//initialise
		HashMap<String, Village> villageMap = theBot.initVillageList(htmlResourcePage);
	}
	
		
	public boolean runContainerOfScripts(ScriptContainer localScriptContainer){
		boolean returnBoolean = true;
		
		// initialise the bot.
		try {
			initBot(bot, this.username, this.password);
		} catch (TravianBotException tbe) {
			log.error("unable to initialise the travian bot: "+tbe.getMessage());
			
			tbe.printStackTrace();
			returnBoolean= false;
		}								
		
		if(returnBoolean){	
			// move to the first script
			localScriptContainer.backToStart();
			
			// run each script
			TravianScript script = localScriptContainer.getNextScript();
			while(script != null){
				try {
					//runResourceScript(script);
					script.runScript(this.bot, localScriptContainer.getScriptSessionInfo());
				} catch (TravianBotException e) {
					log.error("Problem running script: "+script);
					log.error("exception: "+e);
					e.printStackTrace();
				}
				script = localScriptContainer.getNextScript();
				
			}
		}
		
		return returnBoolean;
	}
	
	/**
	 * method to execute all of the scripts
	 */
	public void run(){
		int loopCounter = 0;
					
		// main loop for the thread
		while(this.stillRunning){
			
			runContainerOfScripts(scriptContainer);
			
			// check for attacks
			try {
				log.info("Checking for attacks");
				bot.allertOnAttacks();				
			} catch (TravianBotException e1) {
				log.error("Problems checking for attacks"+e1);
				e1.printStackTrace();
			}
			
			// display all of the collected resource details
			//bot.printVillageDetails();
			//System.out.println(bot.getAccount().printCSVOutput());
			
			try {
				Random generator = new Random();
				int minsToSleep = this.sleepMinutes + generator.nextInt(20);
		        long numMillisecondsToSleep = minsToSleep * 60 * 1000; // min * sec * milliseconds
		        log.info("Sleeping mins:"+minsToSleep);
		        sleep(numMillisecondsToSleep);
		    } catch (InterruptedException e) {
		    	log.warn("Thread interrupted!?");
		    }
		    loopCounter++;
		    if(loopCounter >= this.loopMax){
		    	this.stillRunning = false;
		    }
		}
	}

	public ScriptContainer getScriptContainer() {
		return scriptContainer;
	}

	public void setScriptContainer(ScriptContainer scriptContainer) {
		this.scriptContainer = scriptContainer;
	}
		
	
	public static TravianScript getResourceScriptFromCSVLine(String csvLine){
		//ResourceScript resourceScript = null;
		TravianScript resourceScript = null;
		
		//cursor_position,village_name,type,entry:level,entry:level,.....
		csvLine = csvLine.trim();
		
		if(csvLine.length() > 1  && csvLine.startsWith("#") != true){
			
			resourceScript = TravianScript.getResourceScriptFactory(csvLine);			
		}
		
		return resourceScript;		
	}
	
	
	public static HashMap<String,String> getPropertiesFromFile(String fileContents){
		HashMap<String,String> returnMap = new HashMap<String,String>();
		
		String[] configurationArray = fileContents.split(NEWLINE);
		String line;
		for (int i = 0; i < configurationArray.length; i++) {
			line = configurationArray[i];
			if(line.startsWith("prop.")){
				line = line.replaceFirst("prop.", "");
				String[] tokens = line.split("=");
				returnMap.put(tokens[0], tokens[1]);				
			}			
		}
		return returnMap;
	}
	
	/**
	 * collect the script lines from the config file
	 * @param fileContents
	 * @return
	 */
	public static ScriptContainer getScriptsFromFile(String fileContents){
		ScriptContainer scriptContainer = new ScriptContainer();
		
		String[] configurationArray = fileContents.split(NEWLINE);
		String line;
		TravianScript resourceScript;
		for (int lineNumber = 0; lineNumber < configurationArray.length; lineNumber++) {
			line = configurationArray[lineNumber].trim();
			if(!line.startsWith("prop.") && !line.startsWith("#")){
				resourceScript = getResourceScriptFromCSVLine(line);
				if(resourceScript != null){					
					scriptContainer.addScript(resourceScript, lineNumber);
				}
			}			
		}
		return scriptContainer;
	}
	
	public static void main(String[] args) throws IOException{
		TravianScriptRunner runner = new TravianScriptRunner();
		
		// setup some scripts
		// TODO: load these from a file
		ScriptContainer scriptContainer = new ScriptContainer();		
		
		String propertiesFile = "travianbot.properties";
		if(args.length == 1){
			propertiesFile=args[0];
		}
		
		String fileAsString = TravianBotUtil.getFileAsString(propertiesFile);
		scriptContainer = getScriptsFromFile(fileAsString);
		
		runner.setScriptContainer(scriptContainer);
		
		runner.loopMax = 1000;
		runner.start();		
	}

	public TravianBot getBot() {
		return bot;
	}

	public void setBot(TravianBot bot) {
		this.bot = bot;
	}
	
}
